//////////////////////////////////////////////
// TabWindow.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Forward decl -----------------------------

namespace nkWinUi
{
	class System ;
	class Window ;
}

/// Includes ---------------------------------

// nkWinUi
#include "Component.h"

#include "../Dll/DllDefines.h"

// nkMemory
#include <NilkinsMemory/Pointers/UniquePtr.h>

// Standards
#include <string>
#include <unordered_map>

/// Class ------------------------------------
	
namespace nkWinUi
{
	class DLL_WINUI_EXPORT TabWindow : public Component
	{
		public :

			// Tab class to keep needed info
			class DLL_WINUI_EXPORT Tab
			{
				public :

					// Constructeur, destructeur
					Tab (TabWindow* parentWindow) noexcept ;
					virtual ~Tab () ;

					// Getters
					nkMemory::StringView getLabel () const ;
					Window* getAssociatedWin () const ;
					int getId () const ;
					TabWindow* getParentWindow () const ;

					// Setters
					virtual void setLabel (nkMemory::StringView label, bool autoUpdate = true) ;
					void setAssociatedWin (Window* win) ;
					void setId (int id) ;

				protected :
						
					// Attributes
					nkMemory::String _label ;
					Window* _associatedWin ;
					TabWindow* _parentWindow ;
					int _id ;
			} ;
		
		public :
		
			// Constructor, destructor
			TabWindow (System* system) noexcept ;
			virtual ~TabWindow () ;

			// For tabs
			virtual Tab* addTab (nkMemory::StringView label) ;
			Tab* getTabByLabel (nkMemory::StringView label) const ;
			Tab* getTabById (int id) const ;
			Tab* getTabByIndex (unsigned int index) const ;
			virtual Tab* getTabByMouseRel (nkMaths::Point mouseRel) const = 0 ;
			int getTabIndex (Tab* tab) const ;
			unsigned int getTabCount () const ;
			virtual void reorderTab (Tab* tab, unsigned int newIndex) ;
			virtual void eraseTab (Tab* tab) ;

			// Concerning layouts
			virtual Layout* setLayout (LAYOUT_TYPE layoutType) override ;

			// Active tab
			virtual void setActiveTab (Tab* toActivate) ;
			Tab* getActiveTab () const ;

			// Sizing inside
			virtual void adaptToDisplayArea (Window* toAdapt) const = 0 ;

			// Callbacks
			void setTabSwitchCallback (std::function<bool (TabWindow*, TabWindow::Tab*, bool)> value) ;
			const std::function<bool (TabWindow*, TabWindow::Tab*, bool)>& getTabSwitchCallback () const ;

			// Import / Export
			virtual void exportIntrospection (nkExport::Node* rootNode) override ;
			virtual void importClassFromTree (nkExport::Node* rootNode) override ;

		public :

			// Statics
			static nkMemory::UniquePtr<TabWindow> create (System* system = nullptr) ;

		protected :

			// Functions
			virtual Tab* _allocateTab (TabWindow* parentWindow) const = 0 ;

		protected :
		
			// Attributes
			// Tabs, also associated to an id for identifying
			std::unordered_map<int, Tab*> _indicesMemory ;
			std::vector<Tab*> _tabs ;

			// Active tab
			Tab* _activeTab ;

			// Callback when changing tab
			std::function<bool (TabWindow*, TabWindow::Tab*, bool)> _tabSwitchCallback ;
	} ;
}